package com.katze.boot.plugins.feign;

import feign.Feign;
import feign.Request;
import feign.RequestTemplate;
import feign.Target;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.openfeign.FeignClientFactoryBean;
import org.springframework.cloud.openfeign.FeignContext;
import org.springframework.cloud.openfeign.Targeter;

import java.net.URI;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 说  明：
 * 作  者：zf.zeng
 * 日  期：2022-12-15 (星期四)
 **/
public class RouteTargeter implements Targeter {

    private static final URI defaultUri = URI.create("");

    private static final Map<String, AccessManager> address = new ConcurrentHashMap<>();

    private final FeignContext context;

    public RouteTargeter (FeignContext context) {
        this.context = context;
    }

//    public ApplicationInnerService getApplicationInnerService() {
//        if (service == null) {
//            service = context.getInstance(ApplicationInnerService.class.getSimpleName(), ApplicationInnerService.class);
//        }
//        return service;
//    }

    @Override
    public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context, Target.HardCodedTarget<T> target) {
        return feign.target(new RouteTarget<>(target));
    }

    public static URI get(String groupId) {
        return StringUtils.isBlank(groupId) ?  defaultUri : address.get(groupId).getUri(groupId);
    }

    public static URI get(String groupId, String serviceId) {
        return StringUtils.isBlank(groupId) ?  defaultUri : address.get(groupId).getUri(serviceId);
    }

    public void add(FeignUri uri){
        address.computeIfAbsent(uri.getGroupId(), AccessManager::new).add(uri);
    }

    public void remove(FeignUri uri){
        address.computeIfPresent(uri.getGroupId(), (k, v)-> v.remove(uri) == 0? null : v);
    }

    public static class RouteTarget<T> implements Target<T> {

        private final Target<T> target;

        public RouteTarget(Target<T> target) {
            super();
            this.target = target;
        }

        @Override
        public Class<T> type() {
            return target.type();
        }

        @Override
        public String name() {
            return target.name();
        }

        @Override
        public String url() {
//            AccessManager manager = address.get(name());
//            if (manager == null) {
//                throw new ApplicationNotExistException("当前应用程序处于离线状态暂时无法访问");
//            }
//            return manager.getUri().toString();
            return "";
        }

        @Override
        public Request apply(RequestTemplate input) {
//            if (input.url().indexOf("http") != 0) {
//                input.target(url());
//            }
            return input.request();
        }

    }
}
